# data14_analysis.py
import numpy as np
import math
import os

# 创建静态文件夹（如果不存在）
STATIC_DIR = 'static/images'
os.makedirs(STATIC_DIR, exist_ok=True)

def tem_curve(data):
    """温度曲线数据生成"""
    try:
        date = []
        low_tem = []
        high_tem = []
        
        for row in data:
            try:
                # 安全地提取并转换数据
                d = str(row[0]) if row[0] else "未知"
                
                lt_valid = row[2] if len(row) > 2 else ""
                ht_valid = row[3] if len(row) > 3 else ""
                
                try:
                    lt = float(lt_valid) if lt_valid and lt_valid != "" else 0
                    if math.isnan(lt):
                        lt = 0
                except (ValueError, TypeError):
                    lt = 0
                
                try:
                    ht = float(ht_valid) if ht_valid and ht_valid != "" else 0
                    if math.isnan(ht):
                        ht = 0
                except (ValueError, TypeError):
                    ht = 0
                
                date.append(d)
                low_tem.append(lt)
                high_tem.append(ht)
            except (IndexError, ValueError, TypeError) as e:
                print(f"处理行数据出错: {str(e)}, 行数据: {row}")
                continue
        
        # 确保数据不为空
        if not date or not low_tem or not high_tem or len(date) < 2:
            # 返回默认数据
            default_dates = ["Day 1", "Day 2", "Day 3", "Day 4", "Day 5", "Day 6", "Day 7"]
            return {
                'xAxis': default_dates,
                'series': [
                    {'name': '最高温度', 'type': 'line', 'data': [20] * 7},
                    {'name': '最低温度', 'type': 'line', 'data': [10] * 7}
                ],
                'min': 5,
                'max': 25,
                'avg_high': 20,
                'avg_low': 10
            }
        
        # 计算统计数据
        tem_min = min(low_tem)
        tem_min_date = date[low_tem.index(tem_min)]
        tem_max = max(high_tem)
        tem_max_date = date[high_tem.index(tem_max)]
        low_tem_avg = sum(low_tem) / len(low_tem)
        high_tem_avg = sum(high_tem) / len(high_tem)
        
        # 返回ECharts所需的数据
        return {
            'xAxis': date,
            'series': [
                {
                    'name': '最高温度',
                    'type': 'line',
                    'data': high_tem,
                    'markPoint': {
                        'data': [
                            {'value': tem_max, 'xAxis': tem_max_date, 'yAxis': tem_max, 'name': '最高温度'}
                        ]
                    },
                    'markLine': {
                        'data': [
                            {'type': 'average', 'name': '平均最高温度'}
                        ]
                    }
                },
                {
                    'name': '最低温度',
                    'type': 'line',
                    'data': low_tem,
                    'markPoint': {
                        'data': [
                            {'value': tem_min, 'xAxis': tem_min_date, 'yAxis': tem_min, 'name': '最低温度'}
                        ]
                    },
                    'markLine': {
                        'data': [
                            {'type': 'average', 'name': '平均最低温度'}
                        ]
                    }
                }
            ],
            'min': tem_min - 2,
            'max': tem_max + 2,
            'avg_high': high_tem_avg,
            'avg_low': low_tem_avg
        }
    except Exception as e:
        # 发生任何错误时返回默认数据
        print(f"温度曲线数据生成错误: {str(e)}")
        default_dates = ["Day 1", "Day 2", "Day 3", "Day 4", "Day 5", "Day 6", "Day 7"]
        return {
            'xAxis': default_dates,
            'series': [
                {'name': '最高温度', 'type': 'line', 'data': [20] * 7},
                {'name': '最低温度', 'type': 'line', 'data': [10] * 7}
            ],
            'min': 5,
            'max': 25,
            'avg_high': 20,
            'avg_low': 10
        }


def wind_radar(data):
    """风向雷达图数据生成"""
    try:
        date = []
        wind1 = []
        wind2 = []
        wind_scale = []
        
        for row in data:
            try:
                if len(row) > 6:  # 确保行有足够的列
                    d = str(row[0]) if row[0] else "未知"
                    w1 = str(row[4]) if row[4] else "北风"  # 默认北风
                    w2 = str(row[5]) if row[5] else "北风"  # 默认北风
                    
                    try:
                        ws = float(row[6]) if row[6] and row[6] != "" else 0
                        if math.isnan(ws):
                            ws = 0
                    except (ValueError, TypeError):
                        ws = 0
                    
                    date.append(d)
                    wind1.append(w1)
                    wind2.append(w2)
                    wind_scale.append(ws)
            except (IndexError, ValueError, TypeError) as e:
                print(f"处理风向数据出错: {str(e)}, 行数据: {row}")
                continue
        
        # 确保数据不为空
        if not date or not wind1 or not wind2 or not wind_scale or len(date) < 2:
            # 返回默认数据
            return {
                'indicator': [{'name': dir_name, 'max': 3} for dir_name in ["东北风", "东风", "东南风", "南风", "西南风", "西风", "西北风", "北风"]],
                'series': [{'name': '风级', 'type': 'radar', 'data': [{'value': [1] * 8, 'name': '风级'}]}],
                'max': 3,
                'freq': [12.5] * 8,
                'dirs': ["东北风", "东风", "东南风", "南风", "西南风", "西风", "西北风", "北风"]
            }
        
        # 定义风向名称和角度映射
        wind_dirs = ["东北风", "东风", "东南风", "南风", "西南风", "西风", "西北风", "北风"]
        wind_angles = [45, 0, 315, 270, 225, 180, 135, 90]  # 注意：这里的东风是0度(而不是360，便于计算)
        
        # 将文本风向转为角度
        wind_data = []
        for i in range(len(wind1)):
            # 处理风向1
            angle = 90  # 默认北风
            if wind1[i] == "北风":
                angle = 90
            elif wind1[i] == "南风":
                angle = 270
            elif wind1[i] == "西风":
                angle = 180
            elif wind1[i] == "东风":
                angle = 0
            elif wind1[i] == "东北风":
                angle = 45
            elif wind1[i] == "西北风":
                angle = 135
            elif wind1[i] == "西南风":
                angle = 225
            elif wind1[i] == "东南风":
                angle = 315
            wind_data.append(angle)
            
            # 处理风向2 (如果风向2与风向1不同)
            if i < len(wind2) and wind2[i] != wind1[i]:
                angle = 90  # 默认北风
                if wind2[i] == "北风":
                    angle = 90
                elif wind2[i] == "南风":
                    angle = 270
                elif wind2[i] == "西风":
                    angle = 180
                elif wind2[i] == "东风":
                    angle = 0
                elif wind2[i] == "东北风":
                    angle = 45
                elif wind2[i] == "西北风":
                    angle = 135
                elif wind2[i] == "西南风":
                    angle = 225
                elif wind2[i] == "东南风":
                    angle = 315
                wind_data.append(angle)
        
        # 统计每个方向的风频率和平均风速
        wind_freq = [0] * 8
        wind_speed_sum = [0] * 8
        wind_count = [0] * 8
        
        for i in range(len(wind_data)):
            wind_deg = wind_data[i]
            try:
                wind_sp = wind_scale[min(i // 2, len(wind_scale)-1)]  # 注意：由于风向1和风向2对应同一个风级数据
            except IndexError:
                wind_sp = 0
            
            for j in range(len(wind_dirs)):
                if wind_deg == wind_angles[j]:
                    wind_freq[j] += 1
                    wind_speed_sum[j] += wind_sp
                    wind_count[j] += 1
                    break
        
        # 计算每个方向的平均风速
        wind_speed_avg = []
        for i in range(8):
            if wind_count[i] > 0:
                wind_speed_avg.append(wind_speed_sum[i] / wind_count[i])
            else:
                wind_speed_avg.append(0)
        
        # 计算风向频率百分比
        total_count = sum(wind_freq)
        wind_freq_percent = [round(freq / total_count * 100, 1) if total_count > 0 else 0 for freq in wind_freq]
        
        # 计算最大风速，确保至少为1
        max_wind_speed = max(wind_speed_avg) if wind_speed_avg else 0
        max_wind_speed = max(max_wind_speed + 1, 1)
        
        # 返回ECharts所需的数据
        return {
            'indicator': [{'name': wind_dirs[i], 'max': max_wind_speed} for i in range(8)],
            'series': [
                {
                    'name': '风级',
                    'type': 'radar',
                    'data': [
                        {
                            'value': wind_speed_avg,
                            'name': '风级'
                        }
                    ]
                }
            ],
            'max': max_wind_speed,
            'freq': wind_freq_percent,
            'dirs': wind_dirs
        }
    except Exception as e:
        # 发生任何错误时返回默认数据
        print(f"风向雷达图数据生成错误: {str(e)}")
        return {
            'indicator': [{'name': dir_name, 'max': 3} for dir_name in ["东北风", "东风", "东南风", "南风", "西南风", "西风", "西北风", "北风"]],
            'series': [{'name': '风级', 'type': 'radar', 'data': [{'value': [1] * 8, 'name': '风级'}]}],
            'max': 3,
            'freq': [12.5] * 8,
            'dirs': ["东北风", "东风", "东南风", "南风", "西南风", "西风", "西北风", "北风"]
        }


def weather_pie(data):
    """天气类型饼图数据生成"""
    try:
        weather_types = []
        
        for row in data:
            try:
                if len(row) > 1:  # 确保行有足够的列
                    w_type = str(row[1]) if row[1] else "未知"
                    weather_types.append(w_type)
            except (IndexError, ValueError, TypeError) as e:
                print(f"处理天气类型数据出错: {str(e)}, 行数据: {row}")
                continue
        
        # 确保数据不为空
        if not weather_types:
            # 返回默认数据
            return {
                'data': [
                    {'name': '晴', 'value': 3},
                    {'name': '多云', 'value': 2},
                    {'name': '阴', 'value': 1},
                    {'name': '雨', 'value': 1}
                ]
            }
        
        # 计算各类型天气出现的次数
        weather_counts = {}
        for w_type in weather_types:
            # 提取主要天气类型 (例如: "多云转晴" -> "多云")
            main_type = w_type.split('转')[0] if '转' in w_type else w_type
            if main_type in weather_counts:
                weather_counts[main_type] += 1
            else:
                weather_counts[main_type] = 1
        
        # 转换为饼图所需的格式
        pie_data = []
        for weather_type, count in weather_counts.items():
            pie_data.append({
                'name': weather_type,
                'value': count
            })
        
        # 返回ECharts所需的数据
        return {
            'data': pie_data
        }
    except Exception as e:
        # 发生任何错误时返回默认数据
        print(f"天气类型饼图数据生成错误: {str(e)}")
        return {
            'data': [
                {'name': '晴', 'value': 3},
                {'name': '多云', 'value': 2},
                {'name': '阴', 'value': 1},
                {'name': '雨', 'value': 1}
            ]
        }


def tem_change_bar(data):
    """温度变化柱状图数据生成"""
    try:
        date = []
        low_tem = []
        high_tem = []
        
        for row in data:
            try:
                if len(row) > 3:  # 确保行有足够的列
                    d = str(row[0]) if row[0] else "未知"
                    
                    lt_valid = row[2] if len(row) > 2 else ""
                    ht_valid = row[3] if len(row) > 3 else ""
                    
                    try:
                        lt = float(lt_valid) if lt_valid and lt_valid != "" else 0
                        if math.isnan(lt):
                            lt = 0
                    except (ValueError, TypeError):
                        lt = 0
                    
                    try:
                        ht = float(ht_valid) if ht_valid and ht_valid != "" else 0
                        if math.isnan(ht):
                            ht = 0
                    except (ValueError, TypeError):
                        ht = 0
                    
                    date.append(d)
                    low_tem.append(lt)
                    high_tem.append(ht)
            except (IndexError, ValueError, TypeError) as e:
                print(f"处理温度变化数据出错: {str(e)}, 行数据: {row}")
                continue
        
        # 确保数据不为空
        if not date or not low_tem or not high_tem or len(date) < 2:
            # 返回默认数据
            default_dates = ["Day 1", "Day 2", "Day 3", "Day 4", "Day 5", "Day 6", "Day 7"]
            default_diff = [10, 10, 10, 10, 10, 10, 10]
            return {
                'xAxis': default_dates,
                'series': [
                    {
                        'name': '温差',
                        'type': 'bar',
                        'data': default_diff,
                        'itemStyle': {
                            'colorArray': ['#fac858'] * 7
                        },
                        'markPoint': {
                            'data': [
                                {'value': 10, 'xAxis': 'Day 1', 'yAxis': 10, 'name': '最大温差'},
                                {'value': 10, 'xAxis': 'Day 1', 'yAxis': 10, 'name': '最小温差'}
                            ]
                        },
                        'markLine': {
                            'data': [
                                {'type': 'average', 'name': '平均温差'}
                            ]
                        }
                    }
                ],
                'min': 0,
                'max': 15,
                'avg': 10,
                'colors': ['#fac858'] * 7
            }
        
        # 计算温差
        tem_diff = []
        for i in range(len(high_tem)):
            tem_diff.append(high_tem[i] - low_tem[i])
        
        # 计算统计数据
        diff_max = max(tem_diff)
        diff_max_date = date[tem_diff.index(diff_max)]
        diff_min = min(tem_diff)
        diff_min_date = date[tem_diff.index(diff_min)]
        diff_avg = sum(tem_diff) / len(tem_diff)
        
        # 确定柱状图颜色
        colors = []
        for diff in tem_diff:
            if diff <= 5:
                colors.append('#91cc75')  # 绿色 - 温差小
            elif diff <= 10:
                colors.append('#fac858')  # 黄色 - 温差中等
            else:
                colors.append('#ee6666')  # 红色 - 温差大
        
        # 返回ECharts所需的数据
        return {
            'xAxis': date,
            'series': [
                {
                    'name': '温差',
                    'type': 'bar',
                    'data': tem_diff,
                    'itemStyle': {
                        'colorArray': colors  # 自定义颜色数组，前端使用
                    },
                    'markPoint': {
                        'data': [
                            {'value': diff_max, 'xAxis': diff_max_date, 'yAxis': diff_max, 'name': '最大温差'},
                            {'value': diff_min, 'xAxis': diff_min_date, 'yAxis': diff_min, 'name': '最小温差'}
                        ]
                    },
                    'markLine': {
                        'data': [
                            {'type': 'average', 'name': '平均温差'}
                        ]
                    }
                }
            ],
            'min': 0,
            'max': diff_max + 2,
            'avg': diff_avg,
            'colors': colors
        }
    except Exception as e:
        # 发生任何错误时返回默认数据
        print(f"温差柱状图数据生成错误: {str(e)}")
        default_dates = ["Day 1", "Day 2", "Day 3", "Day 4", "Day 5", "Day 6", "Day 7"]
        default_diff = [10, 10, 10, 10, 10, 10, 10]
        return {
            'xAxis': default_dates,
            'series': [
                {
                    'name': '温差',
                    'type': 'bar',
                    'data': default_diff,
                    'itemStyle': {
                        'colorArray': ['#fac858'] * 7
                    },
                    'markPoint': {
                        'data': [
                            {'value': 10, 'xAxis': 'Day 1', 'yAxis': 10, 'name': '最大温差'},
                            {'value': 10, 'xAxis': 'Day 1', 'yAxis': 10, 'name': '最小温差'}
                        ]
                    },
                    'markLine': {
                        'data': [
                            {'type': 'average', 'name': '平均温差'}
                        ]
                    }
                }
            ],
            'min': 0,
            'max': 15,
            'avg': 10,
            'colors': ['#fac858'] * 7
        }


def wind_bar(data):
    """风级柱状图数据生成"""
    try:
        date = []
        wind_scale = []
        
        for row in data:
            try:
                if len(row) > 6:  # 确保行有足够的列
                    d = str(row[0]) if row[0] else "未知"
                    
                    try:
                        ws = float(row[6]) if row[6] and row[6] != "" else 0
                        if math.isnan(ws):
                            ws = 0
                    except (ValueError, TypeError):
                        ws = 0
                    
                    date.append(d)
                    wind_scale.append(ws)
            except (IndexError, ValueError, TypeError) as e:
                print(f"处理风级数据出错: {str(e)}, 行数据: {row}")
                continue
        
        # 确保数据不为空
        if not date or not wind_scale or len(date) < 2:
            # 返回默认数据
            default_dates = ["Day 1", "Day 2", "Day 3", "Day 4", "Day 5", "Day 6", "Day 7"]
            default_wind = [3, 3, 3, 3, 3, 3, 3]
            return {
                'xAxis': default_dates,
                'series': [
                    {
                        'name': '风级',
                        'type': 'bar',
                        'data': default_wind,
                        'itemStyle': {
                            'colorArray': ['#91cc75'] * 7
                        },
                        'markPoint': {
                            'data': [
                                {'value': 3, 'xAxis': 'Day 1', 'yAxis': 3, 'name': '最大风级'},
                                {'value': 3, 'xAxis': 'Day 1', 'yAxis': 3, 'name': '最小风级'}
                            ]
                        },
                        'markLine': {
                            'data': [
                                {'type': 'average', 'name': '平均风级'}
                            ]
                        }
                    }
                ],
                'min': 0,
                'max': 4,
                'avg': 3,
                'colors': ['#91cc75'] * 7
            }
        
        # 计算统计数据
        scale_max = max(wind_scale)
        scale_max_date = date[wind_scale.index(scale_max)]
        scale_min = min(wind_scale)
        scale_min_date = date[wind_scale.index(scale_min)]
        scale_avg = sum(wind_scale) / len(wind_scale)
        
        # 确定柱状图颜色
        colors = []
        for scale in wind_scale:
            if scale <= 3:
                colors.append('#91cc75')  # 绿色 - 微风
            elif scale <= 5:
                colors.append('#fac858')  # 黄色 - 中等风
            else:
                colors.append('#ee6666')  # 红色 - 大风/风暴
        
        # 返回ECharts所需的数据
        return {
            'xAxis': date,
            'series': [
                {
                    'name': '风级',
                    'type': 'bar',
                    'data': wind_scale,
                    'itemStyle': {
                        'colorArray': colors  # 自定义颜色数组，前端使用
                    },
                    'markPoint': {
                        'data': [
                            {'value': scale_max, 'xAxis': scale_max_date, 'yAxis': scale_max, 'name': '最大风级'},
                            {'value': scale_min, 'xAxis': scale_min_date, 'yAxis': scale_min, 'name': '最小风级'}
                        ]
                    },
                    'markLine': {
                        'data': [
                            {'type': 'average', 'name': '平均风级'}
                        ]
                    }
                }
            ],
            'min': 0,
            'max': scale_max + 1,
            'avg': scale_avg,
            'colors': colors
        }
    except Exception as e:
        # 发生任何错误时返回默认数据
        print(f"风级柱状图数据生成错误: {str(e)}")
        default_dates = ["Day 1", "Day 2", "Day 3", "Day 4", "Day 5", "Day 6", "Day 7"]
        default_wind = [3, 3, 3, 3, 3, 3, 3]
        return {
            'xAxis': default_dates,
            'series': [
                {
                    'name': '风级',
                    'type': 'bar',
                    'data': default_wind,
                    'itemStyle': {
                        'colorArray': ['#91cc75'] * 7
                    },
                    'markPoint': {
                        'data': [
                            {'value': 3, 'xAxis': 'Day 1', 'yAxis': 3, 'name': '最大风级'},
                            {'value': 3, 'xAxis': 'Day 1', 'yAxis': 3, 'name': '最小风级'}
                        ]
                    },
                    'markLine': {
                        'data': [
                            {'type': 'average', 'name': '平均风级'}
                        ]
                    }
                }
            ],
            'min': 0,
            'max': 4,
            'avg': 3,
            'colors': ['#91cc75'] * 7
        }


def analyze_weather14(weather_data=None):
    """14天天气预报数据分析"""
    try:
        # 如果直接提供了数据，则使用提供的数据
        if weather_data is not None:
            data = weather_data
        else:
            # 默认提示信息，实际上由于重构，这个分支不应该被执行
            return {"error": "未提供天气数据"}
            
        # 分析数据
        tem_data = tem_curve(data)
        wind_data = wind_radar(data)
        pie_data = weather_pie(data)
        tem_change_data = tem_change_bar(data)
        wind_bar_data = wind_bar(data)
        
        # 合并结果
        result = {
            'tem': tem_data,
            'wind': wind_data,
            'pie': pie_data,
            'tem_change': tem_change_data,
            'wind_bar': wind_bar_data
        }
        
        return result
        
    except Exception as e:
        import traceback
        return {
            "error": f"分析数据时出错: {str(e)}",
            "traceback": traceback.format_exc()
        }
